#include"TCP_SOCKET.hpp"
#include<cassert>
#include<signal.h>


void create_worker(TcpSocket new_sock)
{
    pid_t pid=fork();//创建子进程
    if(pid<0)
    {
        new_sock.Close();
        cout<<"fork error!!!"<<endl;
        return;
    }
    //创建子进程成功
    if(pid>0)//父进程直接返回，子进程进行任务
    {
        return;
    }
    while(1)
    {
        //5.使用新连接继续宁收发数据
        string buf;
        bool ret=new_sock.Recv(&buf);//接收客户端发送的信息
        cout<<"client say:"<<buf<<endl;

        buf.clear();
        cout<<"server say:";
        fflush(stdout);//清空标准输出缓冲区
        cin>>buf;//从键盘中获取数据到buf中
        new_sock.Send(buf);
        if(ret==false)
        {
            new_sock.Close();
            break;
        }
        exit(EXIT_FAILURE);
    }
}
int main(int argc,char* argv[])
{
    if(argc!=3)//通过于宁参数，获取服务端绑定的地址和端口，即需要三个参数，正确表达式为：./tcp_srv xxx.xxx.xxx.xxx  xxxxx
    {
        cout<<"Run program error"<<endl;
        return -1;
    }
    signal(SIGCHLD,SIG_IGN);//显示表达子进程退出信号，避免产生僵尸进程

    string ip=argv[1];//分割指令
    uint16_t port=stoi(argv[2]);
    
    //服务端创建流程
    TcpSocket lsn_sock;//实例化对象
    //1.创建套接字
    assert(lsn_sock.Socket());
    //2.为套接字绑定地址和端口
    assert(lsn_sock.Bind(ip,port));
    //3.开始监听
    assert(lsn_sock.Listen());
    while(1)
    {
        //4.获取新建连接，让子进程代替父进程工作
        TcpSocket new_sock;
        string cli_ip;
        uint16_t cli_port;
        bool ret=lsn_sock.Accept(&new_sock,&cli_ip,&cli_port);
        if(ret==false)//获取一次连接失败，继续循环获取
        {
            continue;
        }
        //获取成功
        cout<<"new connect:"<<ip<<":"<<cli_port<<endl;
        create_worker(new_sock);//创建子进程处理新的连接
    }

    //6.关闭套接字
    lsn_sock.Close();
    return 0;
}